<template>
	<div class="preview-bd" id="preview_bd" v-if="initing">
		<div class="loading" v-if="loading">
			<image class="img" :src="imgs.loading" mode="widthFix"></image>
		</div>
		<template v-for="(item,index) in list" :key="index">
			<preview-json-item :item="item" :zone="base.p.zone" @itemShow="itemShow"></preview-json-item>
		</template>
		<div class="error" v-if="error.status">
			<div class="more"> {{error.text}}</div>
			<button type="default" class="btn" @click="loadMore()">点击加载</button>
		</div>
		<div class="ft" v-else>
			<template v-if="showNextBtn">
				<div class="more"> 剩余{{rate}}%未预览，点击可继续预览 </div>
				<button type="default" class="btn" @click="loadMore()">加载更多</button>
			</template>
			<template v-else>
				<uni-load-more :status="load.status" :contentText="load.loadText"></uni-load-more>
			</template>
		</div>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				initing: true,
				list: [],
				base: {
					// host: 'https://dev-view-json.book118.com',
					host: 'http://192.168.0.105:9012',
					// url: 'ConvertJson',
					url: 'ConvertJsonV1',
					params: {
						id: '',
						url: ''
					},
					p: {
						start: 0,
						end: 50,
						zone: 50
					},
					auto: 1, //是否自动加载数据
					nums: 20, //每次自动加载多少次
					range: 0 //自动加载的范围
				},
				record: {
					preview: 0, //可预览的数量
					actual: 0, //总数量
					remain: 0, //还有多少数量没呈现出来
					current: 0 //当前最新的数量
				},
				// times: {
				// 	init: 0,
				// 	max: 2
				// },
				imgs: {
					loading: '',
					fail: ''
				},
				loading: true,
				error: {
					status: 0,
					text: '加载出错啦！'
				},
				load: {
					status: 'loading',
					loadText: {
						contentnomore: '预览结束啦'
					}
				}
			}
		},
		created() {
			// this.initParams({
			// 	aid: '524735219',
			// 	url: 'http://max.book118.com/file_down/e06f1ddf5827db0f0b9b294988b6d30a.docx',
			// 	s: 0,
			// 	e: 50,
			// 	z: 50
			// }).then(() => {	
			// 	this.init();
			// })
			// this.initParams({
			// 	aid: '524735221',
			// 	url: 'http://max.book118.com/file_down/1111889f4a56557db87324b9002acd1d.doc',
			// 	s: 0,
			// 	e: 50,
			// 	z: 50
			// }).then(() => {
			// 	this.init();
			// })
			// #ifdef H5
			window.previewJson = {
				initParams: this.initParams,
				init: this.init
			};
			// #endif
			// #ifdef MP-WEIXIN
			// this.$emit('')
			// #endif
		},
		computed: {
			showNextBtn() {
				return this.record.current < this.record.actual && !this.base.auto && this.load.status != 'noMore';
			},
			rate() {
				return (+(this.record.remain / this.record.preview) * 100).toFixed(0)
			}
		},
		watch: {
			list: {
				deep: true,
				handler(newVal, oldVal) {
					if (newVal.length >= this.base.range) this.base.auto = 0;
				}
			}
		},
		methods: {
			async initParams(options) {
				if (!options?.aid || !options?.url) {
					return Promise.reject('缺少必要参数aid或url');
				}
				this.initing = true;
				this.base.params.id = options.aid;
				this.base.params.url = options.url;
				if (options?.nums) this.base.nums = options.nums;
				if (options?.auto) this.base.auto = options.auto;
				if (options?.s) this.base.p.start = options.s;
				if (options?.e) this.base.p.end = options.e;
				if (options?.z) this.base.p.zone = options.z;
				this.base.auto = 1;
				this.base.range = 6;
				return true;
			},
			async init() {
				// this.times.init++;
				// if (this.times.init >= this.times.max) {
				// 	this.initFail();
				// 	return;
				// }
				this.list = [];
				const res = await this.getData({
					s: this.base.p.start,
					e: this.base.p.end
				});
				if (res.code == 200) {
					this.setRecord(res.pages, this.base.p.end);
					this.setList(res.list, this.base.p.start, this.base.p.end);
				} else {
					this.initFail();
				}
			},
			/**
			 * 加载下一批数据
			 */
			async next() {
				if (this.record.current > this.record.preview || (this.record.current + this.base.p.zone) > this.record.actual) {
					return this.noMore();
				}
				const for_start = this.record.current;
				const for_end = this.record.current + this.base.p.zone;
				const res = await this.getData({
					s: for_start,
					e: for_end
				});
				if (res.code == 200) {
					this.setRecord(res.pages, for_end);
					this.setList(res.list, for_start, for_end);
				} else {
					this.loadMoreFail();
				}
			},
			setList(list, start, end) {
				let newList = [];
				for (let key in list) {
					if (JSON.stringify(list[key]) != '{}') {
						newList.push(list[key]);
					}
				}
				this.list.push.apply(this.list, [{ s: start, e: end, datas: newList }]);
				if (!newList.length) this.next();
			},
			setRecord(res, end) {
				this.record.actual = res.actual;
				this.record.preview = res.preview;
				this.record.remain = this.record.actual - end > 0 ? this.record.actual - end : 0;
				this.record.current = end;
				this.loading = false;
			},
			initFail() {
				this.error.status = 1;
			},
			loadMoreFail() {
				this.base.auto = 0;
				this.error.status = 1;
			},
			itemShow(o) {
				if (this.base.auto) this.next();
			},
			loadMore() {
				this.error.status = 0;
				this.base.auto = 2;
				this.base.range = this.list.length + this.base.nums;
				this.next();
			},
			noMore() {
				this.load.status = 'noMore';
			},
			/**
			 * 请求json预览数据
			 * @param {Object} o.s 开始段落 必传
			 * @param {Object} o.e 结束段落 必传
			 */
			async getData(o) {
				const result = {
					pages: {},
					list: []
				};
				const res = await uni.request({
					url: `${this.base.host}/${this.base.url}`,
					data: {
						s: o.s,
						e: o.e,
						...this.base.params
					}
				});
				result.code = res.statusCode;
				// if (o.s == 200) result.code = 400;
				if (typeof res.data != 'object') {
					result.list = null;
					result.pages = null;
				} else {
					for (let count in res.data) {
						result.list = res.data[count];
						result.pages.preview = +count;
						result.pages.actual = +count;
					}
				}
				// if (o.s == 0) result.list = [];
				// console.log('result==>',result)
				return result;
			}
		}
	}
</script>
<style scoped lang="scss">
	.preview-bd {
		position: relative;
		padding: 14px 0;
	}
	.loading {
		display: flex;
		justify-content: center;
		position: absolute;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
		z-index: 2;
		padding: 200rpx 0;
		background: #fff;
		.img {
			width: 100rpx;
		}
	}
	.ft,
	.error {
		.more {
			padding: 10rpx 0 20rpx;
			text-align: center;
			font-size: 30rpx;
			color: #666;
		}
		.btn {
			width: 50%;
			height: 80rpx;
			line-height: 80rpx;
			background: transparent;
			border: 1px solid #2878ff;
			font-size: 30rpx;
			color: #2878ff;
			&:after {
				border: 0;
			}
		}
	}
</style>
